﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using WebClass;
using AutoExtractQueryToXMLFile;
using System.Data;

namespace QuerySelectionLabelingTool
{
    public partial class ImportTask : System.Web.UI.Page
    {
        private int factoryDLLCount;
        private int Count
        {
            get { return Convert.ToInt32(ViewState["count"]); }
            set { ViewState["count"] = value; }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            
            if (!IsPostBack)
            {
                ViewState["count"] = 0;
            }
            if (ViewState["SelectCommand"] != null)
            {
                this.SqlDataSourceGetNews.SelectCommand = ViewState["SelectCommand"].ToString();
            }
        }
        private void SaveNewsIDToSession(System.Collections.IEnumerator data)
        {
            List<string> listNewsID = new List<string>();
            while (data.MoveNext())
            {
                string newsID = ((DataRowView)data.Current).Row["ID"].ToString();
                listNewsID.Add(newsID);
            }
            ViewState["QueryNewsID"] = listNewsID;
        }
        private void PutAddNewsCheckBox()
        {
            TemplateField f = new TemplateField();
            f.HeaderText = "Add News";
            f.ItemTemplate = new CheckBoxItem();
            this.gridViewNewsByKey.Columns.Add(f);
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            
            ++factoryDLLCount;
        }
        private string GetFileNameFromDir(string dir)
        {
            return dir.Substring(dir.LastIndexOf('\\') + 1);
        }
        private string GetServerPath()
        {
            return HttpContext.Current.Server.MapPath(".") + "\\";
        }
        private string GetUserName()
        {
            string username = HttpContext.Current.Request.LogonUserIdentity.Name;//User.Identity.Name;
            return username;
        }
        private string GetServerTempFactoryFilePath()
        {
            string dir = GetServerPath() + "TempFactoryFile\\";
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            return dir;
        }
        private string GetServerOutputXMLFilePath()
        {
            string dir = GetServerPath() + "OutputXMLFile\\" + GetUserName() + "\\";
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            return dir;
        }
        private string GetPageDataToInputPackage()
        {
            string connStringToDownloadNews = this.textBoxConnString.Text;
            string queryNewsString = this.textBoxGetNewsString.Text;
            
            List<InputPackage> listInputPkg = new List<InputPackage>();



            string outputXMLFilename = GetServerOutputXMLFilePath() + DateTime.Now.ToFileTime() + ".xml";
            int factoryControlCount = Convert.ToInt32(this.hiddenFieldFactoryControlCount.Value);
            
            for (int i = 0; i < factoryControlCount; ++i)
            {

                string factoryFileID = "factoryControlFile" + i;
                string factorySelectID = "factoryControlSelect" + i;

                HttpPostedFile factoryFile = Page.Request.Files[factoryFileID];
                string factoryFileName = GetFileNameFromDir(factoryFile.FileName);
                if (factoryFileName == "")
                {
                    continue;
                }
                factoryFile.SaveAs(GetServerTempFactoryFilePath() + factoryFileName);

                string factoryClassType = Page.Request.Params[factorySelectID];
                if (factoryClassType == "")
                {
                    continue;
                }

                InputPackage pkg = new InputPackage();
                pkg.FactoryDLLFileName = GetServerTempFactoryFilePath() + factoryFileName;
                pkg.ClassTypeName = factoryClassType;

                string factoryExtractorHidden = "factoryControlExtractorHidden" + i;
                int extractorCount = Convert.ToInt32(Page.Request.Params[factoryExtractorHidden]);
                string dependFactoryFileHidden = "factoryAddFileHidden" + i;
                int dependFactoryFileCount = Convert.ToInt32(Page.Request.Params[dependFactoryFileHidden]);

                //save depend factory file to TempFactoryFile
                for (int j = 0; j < dependFactoryFileCount; ++j)
                {
                    string dependFileID = "factory" + i + "FactoryFile" + j;
                    HttpPostedFile file = Page.Request.Files[dependFileID];
                    string fileName = GetFileNameFromDir(file.FileName);
                    if (fileName == "")
                    {
                        continue;
                    }
                    file.SaveAs(GetServerTempFactoryFilePath() + fileName);
                }

                for (int j = 0; j < extractorCount; ++j)
                {
                    string extractorRadioHiddenID = "extractor" + i + "RadioHidden" + j;
                    string fileOrText = Page.Request.Params[extractorRadioHiddenID];
                    string extractorAppendixID = "extractor" + i + "Appendix" + j;
                    if (fileOrText == "0")
                    {
                        string extractorConfigID = "extractor" + i + "Config" + j;
                        HttpPostedFile f = Page.Request.Files[extractorConfigID];
                        Stream inputStream = Page.Request.Files[extractorConfigID].InputStream;
                        if (inputStream.Length == 0)
                        {
                            continue;
                        }
                        string appendix = Page.Request.Params[extractorAppendixID];
                        if (appendix == "")
                        {
                            continue;
                        }

                        pkg.ListConfigStream.Add(inputStream);
                        pkg.ListStreamAppendix.Add(appendix);
                    }
                    else
                    {
                        string extractorConfigTextID = "extractor" + i + "ConfigText" + j;
                        string key = Page.Request.Params[extractorConfigTextID];
                        if (key == "")
                        {
                            continue;
                        }
                        string appendix = Page.Request.Params[extractorAppendixID];
                        if (appendix == "")
                        {
                            continue;
                        }
                        pkg.ListGroupID.Add(Convert.ToInt32(key));
                        pkg.ListGroupIDAppendix.Add(appendix);
                    }
                }
                listInputPkg.Add(pkg);
            }
            List<string> queryNewsID = (List<string>)ViewState["QueryNewsID"];
            ProduceAllFile pro = new ProduceAllFile(connStringToDownloadNews, queryNewsString, outputXMLFilename,queryNewsID);
            pro.CreateFile(listInputPkg);
            return outputXMLFilename;
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            bool isXMLTask = true;
            string taskPath = "";
            if(this.radioHiddenFieldXMLOrInte.Value == "1")
            {
                isXMLTask = false;
                taskPath = GetPageDataToInputPackage();
            }
            string taskName = TextBoxTaskName.Text;
            string usernames = TextBoxUsernames.Text;
            if (taskName == "")
            {
                labelMsg.Text = "Please input task name.";
                labelMsg.ForeColor = System.Drawing.Color.Red;
                return;
            }
            if (usernames == "")
            {
                labelMsg.Text = "Please input judgers. use semicolon split it.";
                labelMsg.ForeColor = System.Drawing.Color.Red;
                return;
            }
            if (isXMLTask == true)
            {
                if (FileUploadXMLFile.HasFile)
                {
                    string s = FileUploadXMLFile.ID;
                    Stream stream = FileUploadXMLFile.FileContent;
                    CreateTask(taskName, usernames, stream);
                }
                else
                {
                    labelMsg.Text = "Please choose import file.";
                    labelMsg.ForeColor = System.Drawing.Color.Red;
                    return;
                }
            }
            else
            {
                CreateTask(taskName, usernames, File.OpenRead(taskPath));
            }
            //Get info of factory file and config file
            
        }
        private void CreateTask(string taskName, string usernames, Stream stream)
        {
            ImportTaskFromOutside import = new ImportTaskFromOutside();
            string errorMsg = import.Start(taskName, usernames, stream);
            if (errorMsg != "")
            {
                Session.Add("errorMsg", errorMsg);
                labelMsg.Text = errorMsg;
            }
            else
            {
                labelMsg.Text = "Task created successfully";
                labelMsg.ForeColor = System.Drawing.Color.Gray;
                TextBoxTaskName.Text = "";
                TextBoxUsernames.Text = "";
            }
        }

        protected void buttonGetNews_Click(object sender, EventArgs e)
        {
            string method = this.radioButtonListGetNewsMethod.SelectedValue;
            string key = this.textBoxGetNewsString.Text;
            int groupID = Convert.ToInt32(this.textBoxGroupID.Text);
            if (method == "ByKey")
            {
                GetNewsByKey(key, groupID);
            }
            else if (method == "TopN")
            {
                GetNewsTopN(Convert.ToInt32(key),groupID);
            }
        }
        private void GetNewsByKey(string key,int groupID)
        {
            bool isDigit = true;
            try
            {
                Convert.ToInt32(key);
            }
            catch (Exception e)
            {
                isDigit = false;
            }
            string selectCmd = "";
            if (isDigit == true)
            {
                selectCmd = "select top 50 * from NewsItemList where SourceID in (select ID from RSS where GroupID=" + groupID + ") and (Title like '%" + key + "%' or [Description] like '%" + key + "%' or [ID]=" + key + " or SourceID=" + key + ")order by PubDate desc";
            }
            else
            {
                selectCmd = "select top 50 * from NewsItemList where SourceID in (select ID from RSS where GroupID=" + groupID + ") and (Title like '%" + key + "%' or [Description] like '%" + key + "%')order by PubDate desc";
            }
            this.SqlDataSourceGetNews.SelectCommand = selectCmd;
            ViewState["SelectCommand"] = selectCmd;
            System.Collections.IEnumerator data = this.SqlDataSourceGetNews.Select(new DataSourceSelectArguments()).GetEnumerator();
            SaveNewsIDToSession(data);
            this.SqlDataSourceGetNews.DataBind();
            this.gridViewNewsByKey.DataBind();
        }
        private void GetNewsTopN(int topN,int groupID)
        {
            string selectCmd = "select top " + topN + " * from NewsItemList where SourceID in (select ID from RSS where GroupID=" + groupID + ") order by PubDate desc";
            this.SqlDataSourceGetNews.SelectCommand = selectCmd;
            ViewState["SelectCommand"] = selectCmd;
            System.Collections.IEnumerator data = this.SqlDataSourceGetNews.Select(new DataSourceSelectArguments()).GetEnumerator();
            SaveNewsIDToSession(data);
            this.SqlDataSourceGetNews.DataBind();
            this.gridViewNewsByKey.DataBind();
        }

        protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox box = (CheckBox)sender;
            GridViewRow container = (GridViewRow)box.NamingContainer;
            DataControlFieldCell fieldID = (DataControlFieldCell)(container.Controls[0]);
            if (box.Checked == true)
            {
                AddQueryNewsID(fieldID.Text);
            }
            else
            {
                DeleteQueryNewsID(fieldID.Text);
            }
        }
        private void AddQueryNewsID(string newsID)
        {
            List<string> queryNewsID = (List<string>)ViewState["QueryNewsID"];
            if (QueryNewsIDIndex(newsID) == -1)
            {
                queryNewsID.Add(newsID);
                ViewState["QueryNewsID"] = queryNewsID;
            }
        }
        private void DeleteQueryNewsID(string newsID)
        {
            List<string> queryNewsID = (List<string>)ViewState["QueryNewsID"];
            int index = 0;
            if ((index = QueryNewsIDIndex(newsID)) != -1)
            {
                queryNewsID.RemoveAt(index);
                ViewState["QueryNewsID"] = queryNewsID;
            }
        }
        private int QueryNewsIDIndex(string newsID)
        {
            List<string> queryNewsID = (List<string>)ViewState["QueryNewsID"];
            if (queryNewsID != null)
            {
                return queryNewsID.FindIndex(delegate(string s)
                {
                    if (s == newsID)
                        return true;
                    return false;
                });
            }
            else
            {
                return 1;
            }
        }
        protected void CheckBox1_DataBinding(object sender, EventArgs e)
        {
            CheckBox box = (CheckBox)sender;
            GridViewRow container = (GridViewRow)box.NamingContainer;
            DataControlFieldCell fieldID = (DataControlFieldCell)(container.Controls[0]);
            if (QueryNewsIDIndex(fieldID.Text) != -1)
            {
                box.Checked = true;
            }
            else
            {
                box.Checked = false;
            }
        }
    }
}